#include "xc.h"
#include "user_interface.h"
#include "osapi.h"
#include "driver/uart.h"

#include "user_app.h"
#include "wix_tcpserver.h"
//#include "wix_webserver.h"

/** @defgroup AT_PORT_Extern_Variables
  * @{
  */
extern uint16_t at_sendLen;
extern uint16_t at_tranLen;
//extern UartDevice UartDev;
//extern bool IPMODE;
extern os_timer_t at_delayChack;
extern uint8_t at_wifiMode;

/** @defgroup AT_PORT_Extern_Functions
  * @{
  */  
extern void at_ipDataSending(uint8_t *pAtRcvData);
extern void xc_flow_onUart(uint8_t a_uart);

BOOL specialAtState = TRUE;
at_stateType  at_state;
uint8_t *pDataLine;
BOOL echoFlag = TRUE;

static uint8_t at_cmdLine[at_cmdLenMax];
uint8_t at_dataLine[at_dataLenMax];/////
//uint8_t *at_dataLine;

LOCAL os_timer_t client_timer;
LOCAL uint16_t ncount=0;

/** @defgroup AT_PORT_Functions
  * @{
  */

void ICACHE_FLASH_ATTR 	smart_Init(void);
void ICACHE_FLASH_ATTR 	on_APconfig(void);
void ICACHE_FLASH_ATTR 	on_APconnect(uint8 check_flag);
uint8 ICACHE_FLASH_ATTR  	get_connect_status(void);

void blinky(void);

//路由器连接状态
typedef struct {
	uint8_t sID;														//状态ID长度。
	char *sInfo;													//状态名称。
}	capstatusInfo;

capstatusInfo capsInfo[] ={
	{0,"STATION_IDLE"},
	{1,"STATION_CONNECTING"},
	{2,"STATION_WRONG_PASSWORD"},
	{3,"STATION_NO_AP_FOUND"},
	{4,"STATION_CONNECT_FAIL"},
	{5,"STATION_GOT_IP"}
};

//GPIO状态
typedef struct {
	uint8_t sID;														//状态ID长度。
	uint8_t sPin;													//状态名称。
	uint8_t status;
}	gpioStatusInfo;

gpioStatusInfo gpiosInfo[] ={
	{0,BIT0,0},
	{1,BIT1,0},
	{2,BIT2,0},
	{3,BIT3,0},
	{4,BIT4,0},
	{5,BIT5,0}
};

//*************************//
//My Application Start...
/**
  * @brief  Initializes build two tasks.
  * @param  None
  * @retval None
  */
void ICACHE_FLASH_ATTR
app_init(void)
{
	//建立两个系统运行任务。
	system_os_task(app_busyTask, app_busyTaskPrio, app_busyTaskQueue, app_busyTaskQueueLen);
	system_os_task(app_procTask, app_procTaskPrio, app_procTaskQueue, app_procTaskQueueLen);

	wifi_set_opmode(STATIONAP_MODE);

	//user_devicefind_init();
	//#ifdef SERVER_SSL_ENABLE
	//    user_webserver_init(SERVER_SSL_PORT);
	//#else
	//webserver_init(SERVER_PORT);
	//wifi_station_dhcpc_start();
	//tcpserver_init(SERVER_PORT);
	//#endif
	smart_Init();
	//gpio_init();
	blinky();
}

/*****************************************************
 *开机测试程序。 
 *****************************************************/
void ICACHE_FLASH_ATTR T_JoinAP(void)
{
//	#if 0
//    {
        char sofap_mac[6] = {0x16, 0x34, 0x56, 0x78, 0x90, 0xab};
        char sta_mac[6] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab};
        struct ip_info info;

        wifi_set_macaddr(SOFTAP_IF, sofap_mac);
        wifi_set_macaddr(STATION_IF, sta_mac);

        IP4_ADDR(&info.ip, 192, 168, 1, 8);
        IP4_ADDR(&info.gw, 192, 168, 1, 1);
        IP4_ADDR(&info.netmask, 255, 255, 255, 0);
        wifi_set_ip_info(STATION_IF, &info);

        IP4_ADDR(&info.ip, 10, 10, 10, 1);
        IP4_ADDR(&info.gw, 10, 10, 10, 1);
        IP4_ADDR(&info.netmask, 255, 255, 255, 0);
        wifi_set_ip_info(SOFTAP_IF, &info);
//    }
//#endif
	//set ap.
	xc_connectAP("HiWiFi_SMT","87654321");
	//wifi_station_connect();	
}

/*****************************************************
 *AP配置三种状态， 
 *****************************************************/
void ICACHE_FLASH_ATTR smart_Init(void)
{
	//读入启动参数-用户设备运行参数，如定时器，开关等（AP参数系统自动运行）。
	//T_JoinAP();
	
	//连接无线路由器。参数为空，则直接进入连接状态。
	char temp[64];
	struct station_config stationConf;
	if (wifi_station_get_config(&stationConf)==TRUE) {
		if (stationConf.ssid[0]=='\0') {
			on_APconfig();
			return;
		}
		os_sprintf(temp, "\r\nConnect to AP:%s\r\n", stationConf.ssid);
		uart0_sendStr(temp);
	}
	
	wifi_station_set_auto_connect(1);
	
	//设置检测定时器，如果连接不成功，定期重连。
	//uint8 isAutoConn = wifi_station_get_auto_connect();
	//os_sprintf(temp, "\r\nAutoConnect=%d\r\n",isAutoConn);
	//uart0_sendStr(temp);

	on_APconnect(0);	//等待AP连接成功。
	//成功连接后，保存参数。
}

//AP参数无效时，启动softAP和TCPServer at 192.168.4.1:8268.
void ICACHE_FLASH_ATTR on_APconfig(void)
{
		char temp[64];
		wifi_set_opmode(STATIONAP_MODE);
		tcpserver_start();
		os_sprintf(temp, "\r\nPlease config AP,Find ESP_XXX and connect to 192.168.4.1:8268\r\n");
		uart0_sendStr(temp);
		//通过LED灯等提醒用户需要重新配置。
		//...
}

//等待AP连接，如果连接失败，进入初始配置状态。
void ICACHE_FLASH_ATTR on_APconnect(uint8 check_flag)
{
	char temp[64];
    struct ip_info ipconfig;
	
	//uart0_sendStr("\r\nCheck IP.\r\n");
	os_timer_disarm(&client_timer);
	
	//uart0_sendStr("\r\nGET IP.\r\n");
	wifi_get_ip_info(STATION_IF, &ipconfig);
	
	//uart0_sendStr("\r\nGET STATUS.\r\n");
	//uint8 ap_status = (uint8)wifi_station_get_connect_status();
	//uart0_sendStr("\r\nGET STATUS OK.\r\n");

	//if (ap_status == STATION_GOT_IP && ipconfig.ip.addr != 0) {	//连接成功。
	if ( ipconfig.ip.addr != 0) {	
		os_sprintf(temp, "connected: %d.%d.%d.%d\r\n", IP2STR(&ipconfig.ip));
		uart0_sendStr(temp);
		tcpserver_start();
		os_sprintf(temp, "Start IP Server: %d\r\n", get_tcpserver());
		uart0_sendStr(temp);
		//通过LED灯等提醒用户配置成功。
		//...
	} else {
		ncount ++;
		if (ncount<10) {
			//if ((ap_status>=0)&&(ap_status<=5)) {
			//	os_sprintf(temp, "waiting %d/9, status %d-%s...\r\n",ncount,ap_status, capsInfo[ap_status].sInfo);
			//} else {
			//	os_sprintf(temp, "waiting %d/9, status %d...\r\n",ncount,ap_status);
			//}
			os_sprintf(temp, "waiting %d/9 ...\r\n",ncount);  
			uart0_sendStr(temp);
			os_timer_setfn(&client_timer, (os_timer_func_t *)on_APconnect, NULL);
			os_timer_arm(&client_timer, 2000, 0);
		} else {
			ncount=0;			//重试连接次数复位。
			on_APconfig();	//多次连接不成功，回到AP模式，等待重新设置参数。
		}
	}
}

//开机的智能连接：判断AP是否可用，连接到AP，如果无效-进入AP状态。
uint8 ICACHE_FLASH_ATTR  get_connect_status(void)
{
    uint8 status = wifi_station_get_connect_status();
    if (status == STATION_GOT_IP) {
        //status = (device_status == 0) ? DEVICE_CONNECTING : device_status;
    }
    //ESP_DBG("status %d\n", status);
    return status;
}

//==========================================
static volatile os_timer_t some_timer;
void some_timerfunc(void *arg)
{
	//Do blinky stuff
	if (GPIO_REG_READ(GPIO_OUT_ADDRESS) & BIT2)
	{
		//Set GPIO2 to LOW
		gpio_output_set(0, BIT2, BIT2, 0);
	}
	else
	{
		//Set GPIO2 to HIGH
		gpio_output_set(BIT2, 0, BIT2, 0);
	}
}

void blinky(void)
{
	// Initialize the GPIO subsystem.
	gpio_init();
	//Set GPIO2 to output mode
	PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
	//Set GPIO2 low
	gpio_output_set(0, BIT2, BIT2, 0);
	//Disarm timer
	os_timer_disarm(&some_timer);
	//Setup timer
	os_timer_setfn(&some_timer, (os_timer_func_t *)some_timerfunc, NULL);
	//Arm the timer
	//&some_timer is the pointer
	//1000 is the fire time in ms
	//0 for once and 1 for repeating
	os_timer_arm(&some_timer, 1000, 1);
}
/**
  * @brief  串口接收任务，由系统中断调用.
  * @param  events: contain the uart receive data
  * @retval None
  */
void uart_recvTask(uint8_t byteData)
{
	static uint8_t atHead[2];
	static uint8_t *pCmdLine;
	uint8_t temp;

	//temp = events->par;
	//temp = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
	temp = byteData;
	
	//============================
	//send to flow.	add by wangeq.
	xc_flow_onUart(temp);	
	//end.
	return;
}

/**
  * @brief  Task of process command or txdata.
  * @param  events: no used
  * @retval None
  */
static void ICACHE_FLASH_ATTR
app_procTask(os_event_t *events)
{
}

static void ICACHE_FLASH_ATTR
app_busyTask(os_event_t *events)
{
  	switch(events->par)
  	{
	  	case 1:
			uart0_sendStr("\r\nbusy p...\r\n");
			break;
			
	  	case 2:
			uart0_sendStr("\r\nbusy s...\r\n");
			break;
	}
}


/**
  * @}
  */
